//---------------------------------------------------------------------------
#include <vcl.h>
#include <assert.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#include "CShowProgress.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
#define HAUTEUR_FENETRE_1       130
#define LARGEUR_FENETRE_1       350
#define HAUTEUR_FENETRE_2       100
#define LARGEUR_FENETRE_2       300
// Reglage pour la barre de progression
#define ANIMATE_WIDTH           223
#define ANIMATE_HEIGHT           13
//---------------------------------------------------------------------------
// ValidCtrCheck est utilisé est utilisé pour être sûr que les composants créés n'ont
// aucune fonction virtuelle pure.
//---------------------------------------------------------------------------
namespace Cshowprogress
{
    void __fastcall PACKAGE Register()
    {
         TComponentClass classes[1] = {__classid(CShowProgress)};
         RegisterComponents("EIC Outils", classes, 0);
    }
}
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(CShowProgress *)
{
    new CShowProgress(NULL);
}
//---------------------------------------------------------------------------




//---------------------------------------------------------------------------
__fastcall CShowProgress::CShowProgress(TComponent* Owner)
    : TComponent(Owner)
{
    _Init();
}
//---------------------------------------------------------------------------
__fastcall CShowProgress::~CShowProgress()
{
    if (m_Form) Close();
}
//---------------------------------------------------------------------------
void __fastcall CShowProgress::_Init()
{
    try {
        FTitre          = EmptyStr;
        FMessage        = EmptyStr;
        FMessageInfo    = EmptyStr;

        m_Form          = NULL;
        m_Message       = NULL;
        m_MessageInfo   = NULL;
        m_Animate       = NULL;
        m_Cursor        = crDefault;

    } catch(Exception &e) {
        MessageDlg(e.Message, mtError, TMsgDlgButtons() << mbOK, 0);
    }
}
//---------------------------------------------------------------------------
bool __fastcall CShowProgress::_CreateForm()
{
    bool bRetour = false;
    try {
        m_Cursor = Screen->Cursor;

        m_Form = new TForm((TComponent *)0);
        m_Form->BorderStyle = bsDialog;
        m_Form->FormStyle   = fsStayOnTop;
        m_Form->Position    = poOwnerFormCenter;
        m_Form->BorderIcons = m_Form->BorderIcons >> biSystemMenu >> biMinimize >> biMaximize >> biHelp;
        m_Form->Caption     = FTitre;
        Screen->Cursor      = crHourGlass;
        //m_Form->Cursor      = crHourGlass;

        switch (FTypeBar) {
            case BAR_Backup: bRetour = _CreateFormAnimate();  break;
            case BAR_Wait:   bRetour = _CreateFormWait();     break;
            default: assert(false);
        }

    } catch(Exception &e) {
        MessageDlg(e.Message, mtError, TMsgDlgButtons() << mbOK, 0);
    }
    return bRetour;
}
/*---------------------------------------------------------------------------
            Fonction : _CreateFormAnimate()
 Paramètres d'entrée : Aucun
Paramètres de sortie : Aucun
    Valeur retournée : Aucune
         Description : Création dynamique des différents objets à afficher.
                       Contient la description de la fenetre avec Animation
//-------------------------------------------------------------------------*/
bool __fastcall CShowProgress::_CreateFormAnimate()
{
    try {
        m_Form->Height      = HAUTEUR_FENETRE_1;
        m_Form->Width       = LARGEUR_FENETRE_1;

        m_Animate = new TAnimate(m_Form);
        m_Animate->Top       = 0;
        m_Animate->Left      = 10;
        // Affichage du libelle
        m_Message = new TLabel(m_Form);
        m_Message->Caption     = FMessage;
        m_Message->Top         = m_Animate->Top + m_Animate->Height - 20;
        m_Message->Left        = m_Animate->Left;
        m_Message->Transparent = true;
        // Affichage du libelle
        m_MessageInfo = new TLabel(m_Form);
        m_MessageInfo->Caption     = FMessageInfo;
        m_MessageInfo->Top         = m_Message->Top + m_Message->Height + 5;
        m_MessageInfo->Left        = m_Message->Left;
        m_MessageInfo->Transparent = true;
        m_MessageInfo->Font->Style = m_MessageInfo->Font->Style << fsBold;

        if (m_Animate) {
            m_Form->InsertControl(m_Animate);
            // Pour affecter un AVI, il faut automatiquement un parent,
            // cependant lorsque l'on affecte un parent on se retrouve
            // avec une erreur lors de la destruction de la form
            m_Animate->CommonAVI = FCommonAVI;
        }

        if (m_Message    ) m_Form->InsertControl(m_Message);
        if (m_MessageInfo) m_Form->InsertControl(m_MessageInfo);

        Application->ProcessMessages();

    } catch(...) {
        if (m_Message    )  { delete m_Message    ; m_Message     = NULL; }
        if (m_MessageInfo)  { delete m_MessageInfo; m_MessageInfo = NULL; }
        if (m_Animate    )  { delete m_Animate    ; m_Animate     = NULL; }
        if (m_Form       )  { delete m_Form       ; m_Form        = NULL; }
        return false;
    }
    return true;
}
/*---------------------------------------------------------------------------
            Fonction : _CreateFormWait()
 Paramètres d'entrée : Aucun
Paramètres de sortie : Aucun
    Valeur retournée : bool (Creation reussie)
         Description : Création dynamique des différents objets à afficher.
                       Contient la description de la fenetre avec barre de
                       progression
//-------------------------------------------------------------------------*/
bool __fastcall CShowProgress::_CreateFormWait()
{
    try {
        m_Form->Height  = HAUTEUR_FENETRE_2;
        m_Form->Width   = LARGEUR_FENETRE_2;

        // Image de la barre
        m_Animate = new TAnimate(m_Form);
        m_Animate->Height   = ANIMATE_HEIGHT;
        m_Animate->Top      = m_Form->ClientHeight - ANIMATE_HEIGHT - 10;
        m_Animate->Left     = ((LARGEUR_FENETRE_2 - ANIMATE_WIDTH)/2);
        //m_Animate->Transparent = true;

        m_Message = new TLabel(m_Form);
        m_Message->Caption     = FMessage;
        m_Message->Top         = m_Animate->Top - m_Message->Height - 10;
        m_Message->Left        = m_Animate->Left;
        m_Message->Transparent = true;
        m_Message->Font->Style = m_Message->Font->Style << fsBold;

        if (m_Animate) {
            m_Form->InsertControl(m_Animate);
            // Pour affecter un AVI, il faut automatiquement un parent,
            // cependant lorsque l'on affecte un parent on se retrouve
            // avec une erreur lors de la destruction de la form

            // Empeche d'enclencher un reset sur le composant lors de
            // l'affectation de ResName.
            // (http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=13316)
            ((TComponent *)m_Animate)->ComponentState << csLoading;
            m_Animate->ResHandle = (int)HInstance;
            m_Animate->ResName   = "VIDEO_SHOWPROGRESS";
            ((TComponent *)m_Animate)->ComponentState >> csLoading;
            m_Animate->Reset();
        }
        if (m_Message  ) m_Form->InsertControl(m_Message);

        Application->ProcessMessages();

    } catch(...) {
        if (m_Animate  ) { delete m_Animate  ; m_Animate   = NULL; }
        if (m_Message  ) { delete m_Message  ; m_Message   = NULL; }
        if (m_Form     ) { delete m_Form     ; m_Form      = NULL; }
        return false;
    }
    return true;
}
//---------------------------------------------------------------------------


                            //////////////////
                            // DECLENCHEURS //
                            //////////////////
                            
//---------------------------------------------------------------------------
void __fastcall CShowProgress::_SetTitre(AnsiString Valeur )
{
    FTitre = Valeur;
    if (m_Form) { m_Form->Caption = FTitre; m_Form->Refresh(); }
};
//---------------------------------------------------------------------------
void __fastcall CShowProgress::_SetMessage(AnsiString Valeur )
{
    FMessage = Valeur;
    if (m_Message) { m_Message->Caption = Valeur; m_Message->Refresh(); }
};
//---------------------------------------------------------------------------
void __fastcall CShowProgress::_SetMessageInfo(AnsiString Valeur )
{
    FMessageInfo = Valeur;
    if (m_MessageInfo) { m_MessageInfo->Caption = Valeur; m_MessageInfo->Refresh(); }
};
//---------------------------------------------------------------------------
void __fastcall CShowProgress::_SetCommonAVI( TCommonAVI Valeur )
{
    FCommonAVI = Valeur;
    if (m_Animate) { m_Animate->CommonAVI = FCommonAVI; m_Animate->Refresh(); }
}
//---------------------------------------------------------------------------
void __fastcall CShowProgress::_SetActive(bool Valeur)
{
    FActive = Valeur;
    (Valeur)?Open():Close();
}
/*---------------------------------------------------------------------------
            Fonction : Open()
 Paramètres d'entrée : Aucun
Paramètres de sortie : Aucun
    Valeur retournée : Aucune
         Description : Ouverture de la fenetre d'attente
//-------------------------------------------------------------------------*/
void __fastcall CShowProgress::Open()
{
    try {
        if (m_Form) Close();

        if (_CreateForm()) {
            // Activation de l'animation
            if ( m_Animate
              && (FCommonAVI != aviNone || !m_Animate->ResName.IsEmpty()) ) m_Animate->Active = true;
            // Ouverture et traite tous les messages d'affichages
            m_Form->Show(); m_Form->Update();
            FActive = true;

        } else if (m_Form) Close();

    } catch(Exception &e) {
        if (m_Form) Close();
        MessageDlg(e.Message, mtError, TMsgDlgButtons() << mbOK, 0); }
}
/*---------------------------------------------------------------------------
            Fonction : Close()
 Paramètres d'entrée : Aucun
Paramètres de sortie : Aucun
    Valeur retournée : Aucune
         Description : Fermeture et destrcution de la fenêtre
//-------------------------------------------------------------------------*/
void __fastcall CShowProgress::Close()
{
    try {
        if (m_Form) {
            Screen->Cursor = m_Cursor;
            if (m_Message    )  { delete m_Message    ; m_Message     = NULL; }
            if (m_MessageInfo)  { delete m_MessageInfo; m_MessageInfo = NULL; }
            if (m_Animate    )  { delete m_Animate    ; m_Animate     = NULL; }
            if (m_Form       )  { delete m_Form       ; m_Form        = NULL; }
            FActive = false;
        }
    } catch(Exception &e) {
        MessageDlg(e.Message, mtError, TMsgDlgButtons() << mbOK, 0); }
}
//---------------------------------------------------------------------------
